﻿var board = {
    timeControl: 5,
    connectionId: '',
    chessBoard: '',
    game: '',
    gameType: '',
    player1Color: '',
    player1Timer: '',
    player2Timer: '',
    promotionPiece: '',
    //only used for promotion
    moveSource: '',
    moveTarget: '',
    //only used in PlayerVsAI
    lastMove: '',
    
    init: function init(timeControl, player1Color, gameType) {
        board.gameType = gameType;
        board.player1Color = player1Color;
        board.timeControl = timeControl;

        board.game = new Chess();

        //config de la ChessBoard
        //FEN: pion about to be promoted rnbqk1nr/pPpp2pp/3b4/4pp2/8/8/1PPPPPPP/RNBQKBNR
        var config = {
            draggable: true,
            debug: 'alert',
            position: 'start', //'rnbqk1nr/pPpp2pp/3b4/4pp2/8/8/1PPPPPPP/RNBQKBNR',//'start',
            onDragStart: board.onDragStart,
            onDrop: board.onDrop,
            onMouseoutSquare: board.onMouseoutSquare,
            onMouseoverSquare: board.onMouseoverSquare,
            onMoveEnd: board.onMoveEnd,
            onSnapEnd: board.onSnapEnd
        }

        board.chessBoard = new ChessBoard('board', config);

        //black
        if (player1Color === 'Black') {
            board.chessBoard.orientation('black');
        }
            //white or not specified
        else {
            board.chessBoard.orientation('white');
        }

        //bind promotion Events
        $('#btnBishop').on('click', function() {
            board.promotionPiece = 'b';
            board.finishPromotion();
        });
        $('#btnRook').on('click', function () {
            board.promotionPiece = 'r';
            board.finishPromotion();
        });
        $('#btnKnight').on('click', function () {
            board.promotionPiece = 'n';
            board.finishPromotion();
        });
        $('#btnQueen').on('click', function () {
            board.promotionPiece = 'q';
            board.finishPromotion();
        });

        board.updateStatus();

        //initialize timers
        board.player1Timer = new Tock({
            countdown: true,
            interval: 25,
            callback: function () {
                //refresh the timer
                var currentTime = board.player1Timer.msToTime(board.player1Timer.lap());
                $('#player1-clock').val(currentTime);
            },
            complete: board.timesUp
        });

        board.player2Timer = new Tock({
            countdown: true,
            interval: 25,
            callback: function () {
                //refresh the timer
                var currentTime = board.player2Timer.msToTime(board.player2Timer.lap());
                $('#player2-clock').val(currentTime);
            },
            complete: board.timesUp
        });

        board.initMicrotransactions();
    },

    initMicrotransactions: function initMicrotransactions() {
        var hub = $.connection.boardHub;

        hub.client.move = function (source, target) {
            board.makeMove(source, target);
        };

        $.connection.hub.start().done(function () {
            board.connectionId = $.connection.hub.id;

            board.player1Timer.start(board.timeControl/*min*/ * 60/*sec*/ * 1000/*ms*/);
            board.player2Timer.start(board.timeControl/*min*/ * 60/*sec*/ * 1000/*ms*/);
            board.player1Timer.pause();

            board.switchTurn();
        });
    },

    clearTimer: function() {
        var minutes = board.timeControl;
        board.player1Timer.stop();
        board.player2Timer.stop();

        $('#player1-clock').val("00" + ":" + (minutes ? (minutes > 9 ? minutes : "0" + minutes) : "00") + ":00");
        $('#player2-clock').val("00" + ":" + (minutes ? (minutes > 9 ? minutes : "0" + minutes) : "00") + ":00");
    },

    timesUp: function () {
        alert("time's up");
        board.clearTimer();
    },

    switchTurn: function() {
        //Stop the clock if it's running, continue clock if paused.
        board.player1Timer.pause();
        board.player2Timer.pause();

        board.updateStatus();


        if (board.gameType === 'AIVsAI' || board.gameType === 'PlayerVsAI' &&
            ((board.player1Color === 'White' && board.game.turn() === 'b') ||
            (board.player1Color === 'Black' && board.game.turn() === 'w'))) {

            if (board.gameType === 'AIVsAI')
                board.lastMove = null;

            var timeRemaining = 0;
            if (board.player1Color === 'White' && board.game.turn() === 'w') {
                timeRemaining = board.player1Timer.lap();
            } else {
                timeRemaining = board.player2Timer.lap();
            }

            $.ajax({
                url: 'Board/Move',
                type: 'POST',
                dataType: 'json',
                // we set cache: false because GET requests are often cached by browsers
                // IE is particularly aggressive in that respect
                cache: false,
                data: {
                    connectionId: board.connectionId,
                    gameId: $('#GameId').val(),
                    lastMove: board.lastMove,
                    remainingTime: timeRemaining
                }
            });
        }
       

        //check if its the ai turn and if its ai vs ai
        //if the current player is a human, wait for the onDrop
    },

    makeMove: function (moveSource, moveTarget) {
        var move = board.game.move({
            from: moveSource,
            to: moveTarget,
            promotion: board.promotionPiece
        });

        // illegal move
        if (move === null) return 'snapback';

        board.lastMove = moveSource + moveTarget;

        // highlight last move
        if (board.game.turn() === 'w') {
            board.removeHighlights('black');
            $('#board .square-' + moveSource).addClass('highlight-black');
            $('#board .square-' + moveTarget).addClass('highlight-black');
        } else {
            board.removeHighlights('white');
            $('#board .square-' + moveSource).addClass('highlight-white');
            $('#board .square-' + moveTarget).addClass('highlight-white');
        }

        board.chessBoard.position(board.game.fen());

        board.switchTurn();
    },

    finishPromotion: function () {
        $("#divPromotionDialog").hide();
        board.makeMove(board.moveSource, board.moveTarget);
    },

    onDragStart: function (source, piece, position, orientation) {
        if (board.game.game_over() === true || (board.game.turn() === 'w' && piece.search(/^b/) !== -1) || (board.game.turn() === 'b' && piece.search(/^w/) !== -1)) {
            return false;
        }
    },

    onDrop: function (source, target) {
        //if he didnt drop it where it started
        if (source === target)
            return;

        //check if a promotion will happen
        if (target.indexOf("8") > -1 && arguments[2].toString().indexOf("P") > -1) {
            //need a promotion
            board.moveSource = source;
            board.moveTarget = target;
            $("#divPromotionDialog").dialog();
        } else{
            board.makeMove(source, target);
        }
    },

    onMouseoverSquare: function (square, piece) {
        // get list of possible moves for this square
        var moves = board.game.moves({
            square: square,
            verbose: true
        });

        // exit if there are no moves available for this square
        if (moves.length === 0) return;

        // highlight the square they moused over
        board.greySquare(square);

        // highlight the possible squares for this piece
        for (var i = 0; i < moves.length; i++) {
            board.greySquare(moves[i].to);
        }
    },

    onMouseoutSquare: function (square, piece) {
        board.removeHighlights();
    },

    // update the board position after the piece snap
    // for castling, en passant, pawn promotion
    onSnapEnd: function () {
        board.chessBoard.position(board.game.fen());
    },

    onMoveEnd: function (oldPos, newPos) {
        board.removeHighlights();
    },

    updateStatus: function () {
        var status;

        var moveColor = 'White';
        if (board.game.turn() === 'b') {
            moveColor = 'Black';
        }

        // checkmate?
        if (board.game.in_checkmate() === true) {
            status = 'Game over, ' + moveColor + ' is in checkmate.';
            board.clearTimer();
        }

        // draw?
        else if (board.game.in_draw() === true) {
            status = 'Game over, drawn position';
            board.clearTimer();
        }

        // game still on
        else {
            status = moveColor + ' to move';

            // check?
            if (board.game.in_check() === true) {
                status += ', ' + moveColor + ' is in check';
            }
        }

        $('#status').html(status);
        $('#fen').html(board.game.fen());
        $('#pgn').html(board.game.pgn());
    },

    removeHighlights: function (color) {
        $('#board .square-55d63').removeClass('highlight-' + color);
        $('#board .square-55d63').css('background', '');
    },

    greySquare: function (square) {
        var squareEl = $('#board .square-' + square);

        var background = '#a9a9a9';
        if (squareEl.hasClass('black-3c85d') === true) {
            background = '#696969';
        }

        squareEl.css('background', background);
    }
}